package Game;
import java.io.Serializable;
import java.util.*;

/**
 * Inventory.java
 * 
 * This class defines an inventory object. An inventory is used to manage 
 * items of different types in a consistent manner. In this implementation, the items
 * of the inventory are stored in a primitive array with position in the array 
 * given by each item's index key in the InventoryItem class. The class provides methods
 * to add items to the inventory or to get a random item. In its implementation, only one
 * object per type of item is created. For example, whether there are 1 or 3 or 5 
 * or any number of Truck engines in an inventory, only one truck engine item is created 
 * and the quantity is stored within that object. To that end, the items in the inventory 
 * are all instances of the item class and are distinguished by the InventoryItem field 
 * 
 * @author Ryan Goodrich
 * @version 1.7
 */

public class Inventory implements Serializable {

	// create array of integers -- id is item id, value is qty of item
	private int[] inventory;
	private ItemList items;
	private int numberOfItems;
	
	
	/**
	 * Constructor for an inventory object. The constructor creates an empty integer array with
	 * size equal to the total number of different types of items in the game. 
	 * 
	 */
	public Inventory() {
		items = GameDriver.getItemList();
		numberOfItems = 0;
		inventory = new int[items.size()];
	}
	
	/**
	 * This method adds a parameterized quantity of a particular type of item to the inventory
	 * 
	 * @param itemId The id of the item of item to add to the inventory
	 * @param amount The number of items of that type to add to the inventory
	 */
	public void addItem(int itemId , int amount) {
		int valueBeforeAdd = inventory[itemId];
		inventory[itemId] += amount;
		if (inventory[itemId] - valueBeforeAdd > 0)
			numberOfItems ++;
		else
			numberOfItems --;
	}
	
	
	/**
	 * This method calculates the weight of the inventory according to the quantity and weight of each item in the inventory
	 * 
	 * @return An integer representing the total weight of the items in the inventory
	 */
	public int calculateInventoryWeight() {
		int weight = 0;
		for (int itemId = 0; itemId < inventory.length; itemId++)
			weight += inventory[itemId] * items.getItemWeight(itemId);
		return weight;
	}
	
	
	/** 
	 * This method returns the quantity of a particular type of item in the inventory
	 * 
	 * @param itemId The item id of the item that you want to know the size of
	 * @return The number of items of that particular type in the inventory 
	 */
	public int getQuantityOf(int itemId) {
		return inventory[itemId];
	}
	
	/**
	 * Get number of items that have a quantity greater then 0 in the inventory
	 * 
	 * @return Number of items
	 */
	public int getNumberOfItems() {
		int count = 0;
		for ( int i : inventory )
		{
			if ( i != 0)
			{
				count++;
			}
		}
		return count;
	}
	
	/**
	 * This method returns the type of a randomly selected item in the inventory
	 * 
	 * @return The id of a random item in the inventory, -1 if inventory is empty
	 */
	public int getRandomInventoryItemId() {
		Random generator = new Random();
		ArrayList<Integer> usedIds = new ArrayList<Integer>();
		for (int itemId = 0; itemId < inventory.length; itemId++)
			if (inventory[itemId] > 0)
				usedIds.add(itemId);
		if (usedIds.size() == 0)
			return -1;
		return usedIds.get(generator.nextInt(usedIds.size() - 1));
	}
	
	/**
	 * This method gets the amount of food the player has and returns this value
	 * 
	 * @return The amount of food the player has
	 */
	public int getRemainingFood()
	{
		int amount = 0;
		ArrayList<Integer> items = GameDriver.getItemList().getAllIdsWhere("classification", "FOOD");
		if (items.size() != 0)
			for ( int item : items)
				amount += getQuantityOf(item) * Integer.parseInt(GameDriver.getItemList().getRawDataAt(item).get("food_value"));
		return amount;
	}
	
	
	/**
	 * This method decreases the amoung of food the player has
	 * 
	 */
	public void decreaseFood(int amount)
	{
		ArrayList<Integer> items = GameDriver.getItemList().getAllIdsWhere("classification", "FOOD");
		int count = -1;
		int elementAmount = 0;
		while ( amount > 0)
		{
			count++;
			elementAmount = getQuantityOf(items.get(count)) * Integer.parseInt(GameDriver.getItemList().getRawDataAt(items.get(count)).get("food_value"));
			if (elementAmount > amount)
			{
				amount = 0;
				addItem( items.get(count), -(int)(Math.ceil((double)(elementAmount - amount) / Integer.parseInt(GameDriver.getItemList().getRawDataAt(items.get(count)).get("food_value")) )));
			}
			else
			{
				amount = amount - elementAmount;
				addItem( items.get(count), -getQuantityOf(items.get(count)));
			}

		}
	}
}
